﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Memcached.ClientLibrary;
using System.Collections;
using dal;
using System.Threading;

/// <summary>
///MemcachedTools 的摘要说明
/// </summary>
public class MemcachedTools
{
    static Dictionary<string, MemcacheKey> dicKey = new Dictionary<string, MemcacheKey>();
    static Queue<MemcacheKey> queKey = new Queue<MemcacheKey>();
    static Dictionary<string, object> dicHangqing = new Dictionary<string, object>();

    static MemcachedTools()
    {
        String[] serverlist = System.Configuration.ConfigurationManager.AppSettings["newsMemcache"].Split(',');
        SockIOPool pool = SockIOPool.GetInstance("news");
        pool.SetServers(serverlist);
        pool.Initialize();

        String[] serverlist5 = System.Configuration.ConfigurationManager.AppSettings["news2Memcache"].Split(',');
        SockIOPool pool5 = SockIOPool.GetInstance("news2");
        pool5.SetServers(serverlist5);
        pool5.Initialize();

        String[] serverlist1 = System.Configuration.ConfigurationManager.AppSettings["hqMemecache"].Split(',');
        SockIOPool pool2 = SockIOPool.GetInstance("hangqing");
        pool2.SocketTimeout = 5000;

        pool2.SocketConnectTimeout = 5000;
        pool2.SetServers(serverlist1);
        pool2.Initialize();

        String[] serverlistQuotes = System.Configuration.ConfigurationManager.AppSettings["quotesMemecache"].Split(',');
        SockIOPool poolQuotes = SockIOPool.GetInstance("quotes");
        poolQuotes.SocketTimeout = 5000;

        poolQuotes.SocketConnectTimeout = 5000;
        poolQuotes.SetServers(serverlistQuotes);
        poolQuotes.Initialize();

        String[] serverlist3 = System.Configuration.ConfigurationManager.AppSettings["DrMemcache"].Split(',');
        SockIOPool pool3 = SockIOPool.GetInstance("Dr");
        pool3.SocketTimeout = 5000;
        pool3.SocketConnectTimeout = 5000;
        pool3.SetServers(serverlist3[0].Split(','));
        pool3.Initialize();

        SockIOPool pool4 = SockIOPool.GetInstance("Dr2");
        pool4.SocketTimeout = 5000;
        pool4.SocketConnectTimeout = 5000;
        pool4.SetServers(serverlist3[1].Split(','));
        pool4.Initialize();


        Thread thread = new Thread(new ThreadStart(SavaKey));
        thread.Priority = ThreadPriority.Lowest;
        thread.Start();

        Thread thread2 = new Thread(new ThreadStart(DealWith));
        thread2.Priority = ThreadPriority.Lowest;
        thread2.Start();
    }

    /// <summary>
    /// 对外来Memcache做二次缓存，以保证系统任何时候都不会出现故障
    /// </summary>
    private static void DealWith()
    {
        while (true)
        {
            lock (dicHangqing)
            {
                string[] keys = dicHangqing.Keys.ToArray();
                for (int i = keys.Length - 1; i >= 0; i--)
                {
                    string key = keys[i];
                    if (!NewsClient.Add(key, dicHangqing[key], DateTime.Now.AddDays(20)))
                    {
                        NewsClient.Set(key, dicHangqing[key], DateTime.Now.AddDays(20));
                    }
                    dicHangqing.Remove(key);
                }
            }
            Thread.Sleep(5000);
        }
    }

    private static MemcachedClient NewsClient
    {
        get
        {
            MemcachedClient mc = new MemcachedClient();
            mc.PoolName = "news";
            mc.EnableCompression = false;
            return mc;
        }
    }

    private static MemcachedClient News2Client
    {
        get
        {
            MemcachedClient mc = new MemcachedClient();
            mc.PoolName = "news2";
            mc.EnableCompression = false;
            return mc;
        }
    }

    /// <summary>
    /// 行情Client
    /// </summary>
    private static MemcachedClient HangqingClient
    {
        get
        {
            MemcachedClient mc = new MemcachedClient();
            mc.PoolName = "hangqing";
            mc.DefaultEncoding = "gb2312";
            mc.EnableCompression = false;
            mc.PrimitiveAsString = true;
            return mc;
        }
    }

    /// <summary>
    /// 买卖Client
    /// </summary>
    private static MemcachedClient QuotesClient
    {
        get
        {
            MemcachedClient mc = new MemcachedClient();
            mc.PoolName = "quotes";
            mc.DefaultEncoding = "gb2312";
            mc.EnableCompression = false;
            mc.PrimitiveAsString = true;
            return mc;
        }
    }

    private static MemcachedClient DrClient
    {
        get
        {
            MemcachedClient mc = new MemcachedClient();
            mc.PoolName = "Dr";
            mc.DefaultEncoding = "gb2312";
            mc.EnableCompression = false;
            mc.PrimitiveAsString = true;
            return mc;
        }
    }

    private static MemcachedClient Dr2Client
    {
        get
        {
            MemcachedClient mc = new MemcachedClient();
            mc.PoolName = "Dr2";
            mc.DefaultEncoding = "gb2312";
            mc.EnableCompression = false;
            mc.PrimitiveAsString = true;
            return mc;
        }
    }


    public static object GetDr(string key)
    {
        object obj = DrClient.Get(key);
        return obj;
    }

    public static object GetDr2(string key)
    {
        object obj = Dr2Client.Get(key);
        return obj;
    }


    public static object GetHangqing(string key)
    {
        object obj = HangqingClient.Get(key);
        if (obj == null)
        {
            return NewsClient.Get(key);
        }
     
        return obj;
    }

    public static string GetHangqingStr(string key)
    {
        string data = (string)HangqingClient.Get(key);
        if (string.IsNullOrEmpty(data))
        {
            return (string)NewsClient.Get(key);
        }
  
        return data;
    }

    public static object[] GetHangqing(string[] keys)
    {
        object[] objs = HangqingClient.GetMultipleArray(keys);
        for (int i = 0; i < objs.Length; i++)
        {
            if (objs[i] == null)
            {
                objs[i] = NewsClient.Get(keys[i]);
            }
        }
       
        return objs;
    }

    public static object[] GetQuotes(string[] keys)
    {
        object[] objs = QuotesClient.GetMultipleArray(keys);
        for (int i = 0; i < objs.Length; i++)
        {
            if (objs[i] == null)
            {
                objs[i] = NewsClient.Get(keys[i]);
            }
        }

        return objs;
    }

    public static Hashtable GetHangqingHash(string[] keys)
    {
        Hashtable ht = HangqingClient.GetMultiple(keys);
        foreach (string key in ht.Keys)
        {
            if (ht[key] == null)
            {
                ht[key] = NewsClient.Get(key);
            }
        }

       
        return ht;
    }

    /// <summary>
    /// 添加一个缓存
    /// </summary>
    /// <param name="obj">缓存对象</param>
    /// <param name="sj">缓存时间</param>
    public static void Add(string key, object obj, DateTime expiry)
    {
        if (!NewsClient.Add(key, obj, expiry))
        {
            NewsClient.Set(key, obj, expiry);
        }
        MemcacheKey mKey = new MemcacheKey();
        mKey.CTime = DateTime.Now;
        mKey.ExpiredTime = expiry;
        mKey.Key = key;
        queKey.Enqueue(mKey);
    }

    public static void AddDr(string key, object obj, DateTime expiry)
    {
        if (!DrClient.Add(key, obj, expiry))
        {
            DrClient.Set(key, obj, expiry);
        }
        MemcacheKey mKey = new MemcacheKey();
        mKey.CTime = DateTime.Now;
        mKey.ExpiredTime = expiry;
        mKey.Key = key;
        queKey.Enqueue(mKey);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public static object Get(string key)
    {
        return NewsClient.Get(key);
    }

    public static bool Set(string key, object value)
    {
        return NewsClient.Set(key, value);
    }
    static void SavaKey()
    {
        while (true)
        {
            try
            {
                while (queKey.Count > 0)
                {
                    var c = queKey.Dequeue();
                    if (dicKey.Keys.Contains(c.Key))
                    {
                        dicKey[c.Key] = c;
                    }
                    else
                    {
                        dicKey.Add(c.Key, c);
                    }
                }
                CMSEntities cms = new CMSEntities();
                string[] keys = dicKey.Keys.ToArray();
                foreach (var key in keys)
                {
                    if (cms.MemcacheKey.Any(x => x.Key == key))
                    {
                        var temp = cms.MemcacheKey.First(x => x.Key == key);
                        temp.ExpiredTime = dicKey[key].ExpiredTime;
                        temp.CTime = dicKey[key].CTime;
                    }
                    else
                    {
                        cms.MemcacheKey.AddObject(dicKey[key]);
                    }
                    dicKey.Remove(key);
                }
                cms.SaveChanges();
            }
            catch
            {
            }
            Thread.Sleep(2000);
        }
    }

    public static void News2Add(string key, object obj, DateTime expiry)
    {
        if (!News2Client.Add(key, obj, expiry))
        {
            News2Client.Set(key, obj, expiry);
        }
    }

    public static T News2Get<T>(string key)
    {
        return (T)News2Client.Get(key);
    }
}